package com.mihuxiaobaigao.ai.Service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mihuxiaobaigao.ai.Mapper.OperateLogMapper;
import com.mihuxiaobaigao.ai.Mapper.productMapper;
import com.mihuxiaobaigao.ai.Service.productService;
import com.mihuxiaobaigao.ai.anno.Log;
import com.mihuxiaobaigao.ai.pojo.*;
import com.mihuxiaobaigao.ai.pojo.Request.ChatRequest;
import com.mihuxiaobaigao.ai.pojo.Request.ContentItem;
import com.mihuxiaobaigao.ai.pojo.Request.Message;
import com.mihuxiaobaigao.ai.pojo.Response.AiResponse;
import com.mihuxiaobaigao.ai.utils.BoxControlUtils;
import com.mihuxiaobaigao.ai.utils.ImageProcessingUtils;
import com.mihuxiaobaigao.ai.utils.WarehouseManagerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class productServiceImpl implements productService{
    @Autowired
    private productMapper productMapper;
    @Autowired
    private OperateLogMapper operateLogMapper;
    @Autowired
    private RestTemplate restTemplate;
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final String originalPath = "D:\\Compute\\java\\project1\\project\\ImgPackage";
    private BoxControlUtils boxControlUtils = new BoxControlUtils();


    @Override
    @Log
    @Transactional
    public String insert(ProductDTO productDTO) {
        try{
            ImageProcessingUtils.processAndSaveImage(productDTO.getImage(),productDTO.getProduct().getName(),originalPath);

            Product product = productDTO.getProduct();
            product.setCount(0);
            product.setImg(product.getName()+".jpg");
            String tags = productDTO.getTags();
            ProductSize productSize = productDTO.getProductSize();
            String[] split = tags.replaceAll("^\\[(.*)]$", "$1")  // 去掉外围中括号
                    .replaceAll("[^a-zA-Z0-9_\\-\\u4e00-\\u9fa5]", " ")  // 非字母数字和汉字替换为空格
                    .replaceAll("\\s+", " ")  // 多个空格合并为一个
                    .trim()  // 去掉首尾空格
                    .split("\\s+");  // 按空格分割

            String tag1 = null, tag2 = null, tag3 = null;
            if (split.length > 0){
                tag1 = split[0];
                if (split.length > 1){
                    tag2 = split[1];
                }
                if (split.length > 2){
                    tag3 = split[2];
                }
            }
            product.setCategory(-1);
            productMapper.insert(product);
            productMapper.insertTags(product.getName(), tag1,tag2,tag3);
            productMapper.insertSize(product.getName(),productSize.getLength(),productSize.getWidth(),productSize.getHeight());
            return null;
        }catch (IOException e) {
//            // 检测如果失败了，先检查有没有图片保存进来，读取 originalPath 下的图片名
//            String filePath = originalPath + "\\" + productDTO.getProduct().getName();
//
//            try {
//                File file = new File(filePath);
//
//                if (file.exists()) {
//                    boolean result = file.delete();
//                    if (result) {
//                        System.out.println("图片删除成功: " + filePath);
//                    } else {
//                        System.out.println("图片删除失败: " + filePath);
//                    }
//                } else {
//                    System.out.println("图片文件不存在: " + filePath);
//                }
//            } catch (Exception e2) {
//                System.out.println("删除图片时发生错误: " + e.getMessage());
//            }

            return "图片下载失败";
        }
    }

    @Override
    @Log
    @Transactional
    public void add(String name, Integer count) throws Throwable {
        Boolean s = StoreIn(name, count);
        if (!s) {
            System.out.println("仓库存储失败"+s);
        }else{
            Boolean b = openBox(name);
            if (!b) {
                System.out.println("仓库打开出现错误");
            }else{
                productMapper.add(count,name);
            }
        }
    }

    @Override
    @Log
    @Transactional
    public String take(String name, Integer count) throws Throwable {
        Integer count1 = productMapper.getLocalCount(name);
        Integer category = productMapper.getCategory(name);
        if (count1>=count) {
            if (!TakeOut(name,count,category)){
                return "仓库中未能正确取出该物品";
            }else{
                Boolean b = openBox(name);
                if (!b){
                    System.out.println("打开仓库出现错误");
                }else{
                    productMapper.deletByName(name,count);
                }
            }
            return null;
        } else {
            return "仓库中没有这么多物品";
        }

    }

    @Override
    public Page show(Integer pageNum, Integer pageSize) throws IOException {
        List<PageInformation> show = productMapper.show(pageNum*8, pageSize);
        Integer count = productMapper.getCount();
        Page page = new Page();
        page.setRows(show);
        page.setTotal(count);
        return page;
    }

    @Override
    public Tags getTags(String name) {
         return productMapper.getTags(name);
    }

    @Override
    public Integer getAllCount() {
        return productMapper.getAllCount();
    }

    @Override
    public Integer getRating() {
        return operateLogMapper.getRating();
    }

    @Override
    public Integer getCount() {
        return productMapper.getCount();
    }

    @Override
    public List<Map<String, Integer>> getTips() {
        return operateLogMapper.getTips();
    }

    @Override
    public Map<String, Integer> getMsgAndCount(String name) {
        return productMapper.getMsgAndCount(name);
    }

    @Override
    public Page normalRecommand(Integer count) throws IOException {
        Page page = new Page();
        page.setRows(productMapper.normalRecommand(count));
        return page;
    }

    @Override
    public List<String> normalRecommandExpand(Integer count) throws IOException {
        return productMapper.normalRecommandExpand(count);
    }

    @Override
    public Page recommandByTags(String name, Integer count) throws IOException {
        List<String> bySimilarTag = productMapper.findBySimilarTag(name, count);
        if(bySimilarTag.isEmpty()){
            bySimilarTag = productMapper.normalRecommandExpand(count);
        }
        List<PageInformation> informations = new ArrayList<>();
        for (String s : bySimilarTag) {
            PageInformation pageInformation = productMapper.getPageInformation(s);
            informations.add(pageInformation);
        }
        Page page = new Page();
        page.setRows(informations);
        page.setTotal(count);
        return page;
    }

    @Override
    public List<String> recommandProduct(String name) {
        return productMapper.recommandProduct(name);
    }

    @Override
    public void setAuthorization(String authorization, String name) {
        productMapper.setAuthorization(authorization,name);
    }

    @Override
    public void setAgent(String appId, String name) {
        productMapper.setAgent(appId,name);
    }

    @Override
    public AiResponse recommandProductAI(String question, String userName) throws Throwable {
        String url = "https://open.bigmodel.cn/api/llm-application/open/v3/application/invoke";
        HttpHeaders headers = new HttpHeaders();
        UserResult informations = productMapper.findInformations(userName);
        headers.set("Authorization","Bearer "+ informations.getAuthorization());
        headers.set("Content-Type","application/json");
        List<ContentItem> contentItem = new ArrayList<>();
        ContentItem contentItem1 = new ContentItem();
        List<String> strings = productMapper.selectNames();
        contentItem1.setValue("query");
        contentItem1.setType("input");
        contentItem1.setValue("我们仓库内有元器件："+strings.toString()+"。用户提问："+question);
        contentItem.add(contentItem1);
        List<Message> messages = new ArrayList<>();
        Message message = new Message();
        message.setContent(contentItem);
        message.setRole("user");
        messages.add(message);
        ChatRequest chatRequest = new ChatRequest();
        chatRequest.setApp_id(informations.getAppId());
        chatRequest.setStream(false);
        chatRequest.setSend_log_event(false);
        chatRequest.setMessages(messages);
        HttpEntity<Object> entity = new HttpEntity<>(chatRequest,headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        JsonNode rootNode = mapper.readTree(response.getBody());
        String text = null;
        try {
            text = rootNode.path("choices").path(0).path("messages").path("content").path("msg").asText();
        } catch (Exception e) {
            System.out.println("数据解析失败");
            throw e.fillInStackTrace();
        }
        String[] split = text.replaceAll("^\\[(.*)\\]$", "$1")  // 去掉外围中括号
                .replaceAll("[^a-zA-Z0-9_\\-\\u4e00-\\u9fa5]", " ")  // 非字母数字和汉字替换为空格
                .replaceAll("\\s+", " ")  // 多个空格合并为一个
                .trim()  // 去掉首尾空格
                .split("\\s+");// 按空格分割
        AiResponse aiResponse = new AiResponse();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            Integer id = productMapper.getProductIdByName(split[i]);
            if (id == null) {
                System.out.println("推荐的器件有些不存在");
            }else{
                list.add(split[i]);
            }
        }
        if (list.size() > 4) {
            for (int i = 4; i < list.size(); i++) {
                list.remove(i);
            }
        } else if (list.size() < 4 && !list.isEmpty()) {
            List<String> similarTag = productMapper.findBySimilarTag(list.get(0), 4);
            for (int i = 0; i < 4; i++) {
                int j;
                for (j = 0; j < list.size(); j++) {
                    if (similarTag.get(i).equals(list.get(j))) {
                        break;
                    }
                }
                if (j == list.size()) {
                    list.add(similarTag.get(i));
                }
                if (list.size() == 4) {
                    break;
                }
            }
        } else if (list.isEmpty()) {
             list = productMapper.normalRecommandExpand(4);
        }

        Page page = new Page();
        List<PageInformation> pageInformations = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            PageInformation pageInformation = productMapper.getPageInformation(list.get(i));
            pageInformations.add(pageInformation);
        }
        page.setRows(pageInformations);
        page.setTotal(list.size());
        aiResponse.setPage(page);
        return aiResponse;
    }

    @Override
    public AiResponse test(String matter) throws Throwable {
        JsonNode rootNode = mapper.readTree(matter);
        String text = null;
        try {
            text = rootNode.path("choices").path(0).path("messages").path("content").path("msg").asText();
        } catch (Exception e) {
            System.out.println("数据解析失败");
            throw e.fillInStackTrace();
        }
        String[] split = text.replaceAll("^\\[(.*)]$", "$1")  // 去掉外围中括号
                .replaceAll("[^a-zA-Z0-9_\\-\\u4e00-\\u9fa5]", " ")  // 非字母数字和汉字替换为空格
                .replaceAll("\\s+", " ")  // 多个空格合并为一个
                .trim()  // 去掉首尾空格
                .split("\\s+");  // 按空格分割
        AiResponse aiResponse = new AiResponse();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            Integer id = productMapper.getProductIdByName(split[i]);
            if (id == null) {
                System.out.println("推荐的器件有些不存在");
            }else{
                list.add(split[i]);
            }
        }
        if (list.size() > 4) {
            for (int i = 4; i < list.size(); i++) {
                list.remove(i);
            }
        } else if (list.size() < 4 && !list.isEmpty()) {
            List<String> similarTag = productMapper.findBySimilarTag(list.get(0), 4);
            for (int i = 0; i < 4; i++) {
                int j;
                for (j = 0; j < list.size(); j++) {
                    if (similarTag.get(i).equals(list.get(j))) {
                        break;
                    }
                }
                if (j == list.size()) {
                    list.add(similarTag.get(i));
                }
                if (list.size() == 4) {
                    break;
                }
            }
        } else if (list.isEmpty()) {
            list = productMapper.normalRecommandExpand(4);
        }

        Page page = new Page();
        List<PageInformation> pageInformations = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            PageInformation pageInformation = productMapper.getPageInformation(list.get(i));
            pageInformations.add(pageInformation);
        }
        page.setRows(pageInformations);
        page.setTotal(list.size());
        aiResponse.setPage(page);
        return aiResponse;
    }

    @Override
    @Log
    @Transactional
    public void deleteByName(String name) throws Throwable {
        String fileName = productMapper.getImgByName(name);
        String filePath = originalPath + "\\"+fileName;
        Integer category = productMapper.getCategory(name);

        try {
            Boolean b = TakeOut(name, productMapper.getLocalCount(name), category);
            if (!b){
                System.out.println("仓库体积不够");
            }else{
                Boolean b1 = openBox(name);
                if (!b1){
                    System.out.println("仓库打开失败");
                }else{
                    productMapper.deleteTagsByName(name);
                    productMapper.deleteSizeByName(name);
                    productMapper.deleteProductByName(name);
                }
            }
        } catch (Throwable e) {
            System.out.println(e.getMessage());
        }

        try {
            File file = new File(filePath);

            if (file.exists()) {
                boolean result = file.delete();
                if (result) {
                    System.out.println("图片删除成功: " + filePath);
                } else {
                    System.out.println("图片删除失败: " + filePath);
                }
            } else {
                System.out.println("图片文件不存在: " + filePath);
            }
        } catch (Exception e) {
            System.out.println("删除图片时发生错误: " + e.getMessage());
            throw e.fillInStackTrace();
        }
    }

    //存入仓库
    public Boolean StoreIn(String name,Integer count) throws Throwable {
        List<TableForcgy> forcgys = productMapper.getTableForcgyByName();
        ProductSize productSizeByName = productMapper.getProductSizeByName(name);
        WarehouseManagerUtils warehouseManager = new WarehouseManagerUtils
                (forcgys.get(0).getVolume(), forcgys.get(1).getVolume(),
                        forcgys.get(0).getRemain(), forcgys.get(1).getRemain());
        Integer b = warehouseManager.storeItems(name, productSizeByName.getLength() *
                productSizeByName.getWidth() * productSizeByName.getHeight(), count,productMapper.getCategory(name));
        if (b==-1){
            return false;
        }else{
            double warehouse1RemainingVolume = warehouseManager.getWarehouse1RemainingVolume();
            if (warehouse1RemainingVolume == forcgys.get(0).getRemain()){
                productMapper.setTableForcgyByName(warehouseManager.getWarehouse2RemainingVolume(),2);
                if (productMapper.getCategory(name)==-1){
                    productMapper.setCategoryByName(name,2);
                }
            }else{
                productMapper.setTableForcgyByName(warehouse1RemainingVolume,1);
                if (productMapper.getCategory(name)==-1){
                    productMapper.setCategoryByName(name,1);
                }
            }
        }
        return true;
    }

    //从仓库取出
    public Boolean TakeOut(String name,Integer count,Integer category) throws Throwable {
        List<TableForcgy> forcgys = productMapper.getTableForcgyByName();
        ProductSize productSizeByName = productMapper.getProductSizeByName(name);
        WarehouseManagerUtils warehouseManager = new WarehouseManagerUtils
                (forcgys.get(0).getVolume(), forcgys.get(1).getVolume(),
                        forcgys.get(0).getRemain(), forcgys.get(1).getRemain());
        Boolean b = warehouseManager.takeOutItems(name, productSizeByName.getLength() *
                productSizeByName.getWidth() * productSizeByName.getHeight(), count,category);
        if (!b){
            return false;
        }else{
            double warehouse1RemainingVolume = warehouseManager.getWarehouse1RemainingVolume();
            if (warehouse1RemainingVolume == forcgys.get(0).getRemain()){
                productMapper.setTableForcgyByName(warehouseManager.getWarehouse2RemainingVolume(),2);
            }else{
                productMapper.setTableForcgyByName(warehouse1RemainingVolume,1);
            }
        }
        return true;
    }

    public Boolean openBox(String name){
        Integer category = productMapper.getCategory(name);
        if (category == 1) {
            try {
                boxControlUtils.openBox1WithAutoClose();
            } catch (Exception e) {
                System.out.println("打开1失败");
                return false;
            }
        } else if (category == 2) {
            try {
                boxControlUtils.openBox2WithAutoClose();
            } catch (Exception e) {
                System.out.println("打开2失败");
                return false;
            }
        }else{
            System.out.println("仓库查找出现错误");
            return false;
        }
        return true;
    }
}
